

#include "vertexdefinition.h"
#include <stdio.h>

#define GLPTR(x) ((char *)NULL + (x))

VertexDefinition::VertexDefinition (unsigned numberOfSources)
  : numSources (numberOfSources)
  , numStreams (0)
{
    sources = new Source [numberOfSources];
}

VertexDefinition::~VertexDefinition ()
{
    delete [] sources;
}

void VertexDefinition::SetSource (unsigned idx, const GLMMVERTEXDESCRIPTION& desc)
{
    if (desc.Stream >= numStreams)
      {
        numStreams = desc.Stream+1;
      }
    
    sources[idx].desc = desc;
    switch (desc.Type)
    {
        case GLMMDATATYPE_UNSIGNED_BYTE:
          sources [idx].type = GL_UNSIGNED_BYTE;
          break;
        case GLMMDATATYPE_BYTE:
          sources [idx].type = GL_BYTE;
          break;
        case GLMMDATATYPE_UNSIGNED_SHORT:
          sources [idx].type = GL_UNSIGNED_SHORT;
          break;
        case GLMMDATATYPE_SHORT:
          sources [idx].type = GL_SHORT;
          break;
        case GLMMDATATYPE_UNSIGNED_INT:
          sources [idx].type = GL_UNSIGNED_INT;
          break;
        case GLMMDATATYPE_INT:
          sources [idx].type = GL_INT;
          break;
        case GLMMDATATYPE_FLOAT:
          sources [idx].type = GL_FLOAT;
          break;
    }
}

unsigned VertexDefinition::GetNumberOfStreams () const
{
    return numStreams;
}

unsigned VertexDefinition::GetNumberOfDescriptions () const
{
    return numSources;
}

const GLMMVERTEXDESCRIPTION& VertexDefinition::GetDescription (unsigned idx) const
{
    return sources [idx].desc;
}

void VertexDefinition::SetupStreams ()
{
    for (unsigned i=0; i<numSources; i++)
      {
        const Source& src = sources[i];
        switch (src.desc.Map)
        {
            case GLMMVERTEXTYPE_XYZ:
              glVertexPointer (src.desc.Size, src.type, src.desc.Stride, GLPTR(src.desc.Offset));
              glEnableClientState (GL_VERTEX_ARRAY);
              break;
            case GLMMVERTEXTYPE_NORMAL:
              glNormalPointer (src.type, src.desc.Stride, GLPTR(src.desc.Offset));
              glEnableClientState (GL_NORMAL_ARRAY);
              break;
            case GLMMVERTEXTYPE_COLOR:
              glColorPointer (src.desc.Size, src.type, src.desc.Stride, GLPTR(src.desc.Offset));
              glEnableClientState (GL_COLOR_ARRAY);
              break;
            case GLMMVERTEXTYPE_TEXTCOORD:
              glActiveTexture (GL_TEXTURE0 + src.desc.Position);
              glClientActiveTexture(GL_TEXTURE0 + src.desc.Position);
              glTexCoordPointer (src.desc.Size, src.type, src.desc.Stride, GLPTR(src.desc.Offset));
              glEnableClientState (GL_TEXTURE_COORD_ARRAY);
              break;
        }
      }
}